// 手写数字查看器
import React, { Component } from "react";
import "../App.css";
import { imgToVector } from "../common/Common";

class HandWrittenView extends Component{

  constructor(props){
    super(props);

    this.state = {
      dataset    : props.dataset,
      page       : 0,
      letter     : '',
      letterSize : props.size ?props.size :[32, 32],
      rows       : props.rows ?props.rows :10,
      cols       : props.cols ?props.cols :10,
      width  : 10,
      height : 10,
      pageLetters : []
    }

    this.handleLetterChange = this.handleLetterChange.bind(this);
    this.handlePageChange   = this.handlePageChange.bind(this);

    this.clear   = React.createRef();
    this.refresh = React.createRef();

    this.canvas  = React.createRef();
  }

  componentDidMount(){
    const dataset = this.state.dataset;
    const letterSize = this.state.letterSize;
    const rows = this.state.rows;
    const cols = this.state.cols;

    const width   = cols * letterSize[0];
    const height  = rows * letterSize[1];

    const letter  = Object.keys(dataset)[0];
    this.setState({
      letter : letter,
      width  : width,
      height : height,
    });

    this.updatePageLetters(letter, 0);
  }

  handleLetterChange(event){
    const letter = event.target.id;
    this.setState({
      letter:letter,
      page  : 0,
    })

    this.updatePageLetters(letter, 0);
  }

  handlePageChange(event){
    const page = parseInt(event.target.id);
    this.setState({
      page  : page,
    })

    const letter = this.state.letter;
    this.updatePageLetters(letter,page);
  }

  refreshPage(){
    this.updatePageLetters();
  }

  updatePageLetters(letter, page){
    this.clearCanvas();

    if(letter === undefined) letter = this.state.letter;
    if(page   === undefined) page   = this.state.page;

    const dataset = this.state.dataset;
    const letters = dataset[letter];
    const lettersPerPage = this.state.rows * this.state.cols; 

    if(!letters) return ;
    const stPos  = page * lettersPerPage;
    const endPos = (page + 1) * lettersPerPage > letters.length?letters.length:(page + 1) * lettersPerPage;
    
    const pageLetterUrls = letters.slice(stPos, endPos);
    let pageLetters = [];
    for(let i = 0, il = pageLetterUrls.length; i < il; i++){
      fetch(pageLetterUrls[i].url).then((response)=>{return response.text()})
      .then((txt)=>{
        // 绘制手写数字
        this.drawLetter(i, txt);
        pageLetters.push(txt);
        this.setState({
          pageLetters : pageLetters
        })
      })
    }
  }

  _renderLetterMenu(){
    const letters = Object.keys(this.state.dataset);
    return letters.map((item, key)=>
      <button key={key} id={item} 
        style={{backgroundColor:item===this.state.letter?'green':''}}
        onClick={this.handleLetterChange}>
        {item}
      </button>
    );
  }

  _renderPageIndex(){
    const letter  = this.state.letter;
    const dataset = this.state.dataset;
    if(!letter || !dataset) return;
    const lettersPerPage = this.state.rows * this.state.cols;
    const allCount = dataset[letter].length;
    const pages = Math.ceil(allCount / lettersPerPage);
    const pageList = [];
    for(let i = 0; i < pages; i++){
      pageList[i] = i + 1;
    }
    return pageList.map((item, key)=>
      <button key={key} id={key}
        style={{backgroundColor:key===this.state.page?'green':''}} 
        onClick={this.handlePageChange}>
        {item}
      </button>
    );
  }

  clearCanvas(){
    var canvas      = this.canvas.current; //document.getElementById('canvas');
    var ctx         = canvas.getContext('2d');
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data      = imageData.data;

    for (var i = 0; i < data.length; i += 4) {
        data[i]     = 255; // red
        data[i + 1] = 255; // green
        data[i + 2] = 255; // blue
        data[i + 3] = 255
    }
    // console.log(imageData)
    ctx.putImageData(imageData, 0, 0);
  }

  drawLetter(index, txt){
    const imgData = imgToVector(txt)[0];
    const width   = this.state.letterSize[0];
    const height  = this.state.letterSize[1];
    var canvas    = this.canvas.current;
    if(!canvas) return;
    var ctx       = canvas.getContext('2d');
    if(!ctx) return;
    const cols    = this.state.cols;
    
    const offsetTop  = Math.floor (index / cols) * height;
    const offsetLeft = Math.floor (index % cols) * width;

    const imageData  = ctx.getImageData(offsetLeft, offsetTop, width, height);
    const data       = imageData.data;

    for (var i = 0; i < data.length; i += 4) {
        data[i]     = imgData[i / 4]?0:255;     // red
        data[i + 1] = imgData[i / 4]?0:255; // green
        data[i + 2] = imgData[i / 4]?0:255; // blue
        data[i + 3] = 255
    }
    // console.log(imageData)
    ctx.putImageData(imageData, offsetLeft, offsetTop);
  }

  render(){
    return(
      <div>
        <button onClick={this.clearCanvas.bind(this)} ref={this.clear}>清空</button>
        <button onClick={this.refreshPage.bind(this)} ref={this.refresh}>刷新</button>
        <div className="div-flex-row">{this._renderLetterMenu()}</div>
        <div className="div-flex-row">{this._renderPageIndex()}</div>     
        <div className="div-flex-row">   
        <canvas ref={this.canvas} width={this.state.width} height={this.state.height}></canvas>
        </div>
      </div>
    );
  }
}

export default HandWrittenView;